﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.IO.IsolatedStorage;
using System.Security.Cryptography;
using System.Text;
namespace MTGScore
{
    public enum TimerType
    {
        Increasing,
        Decreasing
    }

    public class SavedMatch
    {
        public string player1_name;
        public string player2_name;
        public string center_name;
        public string mana6_name;
        public TimerStatus timer_status;
        public List<SavedMoment> savedMoments;
        public List<int> mana_values;
        public string name;

        public SavedMatch()
        {
            player1_name = "";
            player2_name = "";
            center_name = "";
            timer_status = TimerStatus.Stopped;
            savedMoments = new List<SavedMoment>();
            mana_values = new List<int>(7) { 0, 0, 0, 0, 0, 0, 0 };
            name = "";
        }

        public override string ToString()
        {
            string s = name + "\n";

            for (int i = 0; i < savedMoments.Count; i++)
                s += savedMoments[i].ToString() + "\n";

            return s;
        }
    }
    public enum SavedMomentValueType
    {
        None,
        Player1_Life,
        Player1_Center,
        Player2_Life,
        Player2_Center,
        AutoSaved
    }
    public class SavedMoment
    {
        public int player1_life;
        public int player2_life;
        public int player1_center;
        public int player2_center;
        //public TimeSpan time_span;
        public long timeSpan_Ticks;
        public bool auto_saved;
        public SavedMoment()
        {
            player1_life = 0;
            player1_center = 0;
            player2_center = 0;
            player2_life = 0;
            timeSpan_Ticks = 0;
            auto_saved = false;
        }
        public SavedMoment(int my_life, int opponent_life, int my_center, int opponent_center, TimeSpan time_span)
            : this(my_life, opponent_life, my_center, opponent_center, time_span, false)
        { }
        public SavedMoment(int my_life, int opponent_life, int my_center, int opponent_center, TimeSpan time_span, bool auto_saved)
        {
            this.player1_life = my_life;
            this.player1_center = my_center;
            this.player2_center = opponent_center;
            this.player2_life = opponent_life;
            this.time_span = time_span;
            this.auto_saved = auto_saved;
        }
        string Spaces(int val, int max_spaces)
        {
            int letters = ("" + val).Length;
            string s = "";
            for (int i = letters; i < max_spaces; i++)
                s += " ";
            return s;
        }

        public SavedMomentValueType CompareValues(SavedMoment m)
        {
            //return !auto_saved && !m.auto_saved && player1_life == m.player1_life && player1_center == m.player1_center &&
            //    player2_life == m.player2_life && player2_center == m.player2_center;    
            if (auto_saved != m.auto_saved)
                return SavedMomentValueType.AutoSaved;
            if (player1_life != m.player1_life)
                return SavedMomentValueType.Player1_Life;
            if (player1_center != m.player1_center)
                return SavedMomentValueType.Player1_Center;
            if (player2_life != m.player2_life)
                return SavedMomentValueType.Player2_Life;
            if (player2_center != m.player2_center)
                return SavedMomentValueType.Player2_Center;
            return SavedMomentValueType.None;

        }

        public override string ToString()
        {

            var s = "" + player1_life + Spaces(player1_life, 10) + player1_center + Spaces(player1_center, 10) +
                player2_life + Spaces(player2_life, 10) + player2_center + Spaces(player2_center, 10) +
                time_span.ToString();


            return s;
        }

        [XmlIgnore]
        public TimeSpan time_span
        {
            get
            {
                return new TimeSpan(timeSpan_Ticks);
            }
            set
            {
                timeSpan_Ticks = value.Ticks;
            }
        }
    }
    public class SavedOptions
    {
        public long timeSpan_Ticks;
        public long alertTimeSpan_Ticks;

        //private TimeSpan m_timeSpan;
        //private TimeSpan m_alertTimeSpan;
        public bool allow_Timer;
        public bool alert_time;
        public bool alert_end_time;
        //public bool countDown;
        public bool allow_screen_off;
        public TimerType timerType;
        public bool allow_center_end_game;
        public string center_value;
        public int center_max_value;
        public int hours;
        public int minutes;
        public int seconds;
        public int first_page;
        public bool allow_shortcut_menu;
        public bool semplified;
        /*

        // Public Property - XmlIgnore as it doesn't serialize anyway
        [XmlIgnore]
        public TimeSpan timeSpan
        {
            get { return m_timeSpan; }
            set { m_alertTimeSpan = value; }
        }

        // Pretend property for serialization
        [XmlElement("timeSpan")]
        public long TimeSpanTicks
        {
            get { return m_timeSpan.Ticks; }
            set { m_timeSpan = new TimeSpan(value); }
        }

        // Public Property - XmlIgnore as it doesn't serialize anyway
        [XmlIgnore]
        public TimeSpan alertTimeSpan
        {
            get { return m_alertTimeSpan; }
            set { m_alertTimeSpan = value; }
        }

        // Pretend property for serialization
        [XmlElement("alertTimeSpan")]
        public long AlertTimeSpanTicks
        {
            get { return m_alertTimeSpan.Ticks; }
            set { m_alertTimeSpan = new TimeSpan(value); }
        }

        */
        [XmlIgnore]
        public TimeSpan timeSpan
        {
            get
            {
                return new TimeSpan(timeSpan_Ticks);
            }
            set
            {
                timeSpan_Ticks = value.Ticks;
            }
        }
        [XmlIgnore]
        public TimeSpan alertTimeSpan
        {
            get
            {
                return new TimeSpan(alertTimeSpan_Ticks);
            }
            set
            {
                alertTimeSpan_Ticks = value.Ticks;
            }
        }

        public SavedOptions()
        {
            //m_timeSpan = new TimeSpan(0,45,0);
            //m_alertTimeSpan = new TimeSpan(0, 10, 0);
            timeSpan = new TimeSpan(0, 45, 0);
            alertTimeSpan = new TimeSpan(0, 10, 0);
            allow_Timer = true;
            alert_time = true;
            alert_end_time = true;
            //countDown = false;
            allow_screen_off = true;
            timerType = TimerType.Decreasing;
            allow_center_end_game = false;
            center_value = "Infect";
            center_max_value = 10;
            first_page = 0;
            allow_shortcut_menu = true;
            semplified = false;
        }
        /*public TimeSpan timeSpan
        {
            get
            {
                try
                {
                    return new TimeSpan(hours, minutes, seconds);
                }
                catch (Exception e)
                {
                    e.ToString();
                    return TimeSpan.Zero;
                }
            }
            set
            {
                hours = value.Hours;
                minutes = value.Minutes;
                seconds = value.Seconds;
            }
        }
         */
    }

    public static class Storage
    {

        public static SavedOptions LoadSavedOptions()
        {
            using (var appStorage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (var streamFile = appStorage.OpenFile("SavedOptions.xml", FileMode.OpenOrCreate))
                {
                    try
                    {
                        XmlSerializer serializer = new XmlSerializer(typeof(SavedOptions));
                        using (var reader = new StreamReader(streamFile))
                            return serializer.Deserialize(reader) as SavedOptions;
                    }
                    catch (Exception) { return new SavedOptions(); }
                }
            }
        }

        public static void DeleteSavedOptions()
        {
            using (var appStorage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                appStorage.DeleteFile("SavedOptions.xml");
            }
        }

        public static void SaveSavedOptions(SavedOptions state)
        {
            using (var appStorage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                appStorage.DeleteFile("SavedOptions.xml");
                using (var streamFile = appStorage.OpenFile("SavedOptions.xml", FileMode.OpenOrCreate))
                using (var writer = new StreamWriter(streamFile))
                //write_options_state(writer, entry);
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(SavedOptions));
                    serializer.Serialize(writer, state);
                }
            }
        }

        public static void SaveHistory(string s)
        {
            using (var appStorage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                appStorage.DeleteFile("history.html");
                using (var streamFile = appStorage.OpenFile("history.html", FileMode.OpenOrCreate))
                using (var writer = new StreamWriter(streamFile))
                {
                    writer.Write(s);
                }
            }
        }
        public static string GetHistoryURL()
        {
            return "history.html";
        }


        #region Crack

        public static Byte[] CreateMD5Hash(string input)
        {
            var hashalg = new SHA256Managed();
            var h = hashalg.ComputeHash(Encoding.UTF8.GetBytes(input));
            return h;
        }

        public static bool CheckSavedCrack()
        {
            Byte[] saved = GetCrackFile(true);
            Byte[] hash = App.Crack_Hash;
            if (saved.Length != hash.Length)
                return false;
            for (int i = 0; i < saved.Length; i++)
                if (saved[i] != hash[i])
                    return false;
            return true;

        }

        public static bool CheckCrack(Byte[] hash)
        {
            Byte[] saved = GetCrackFile(false);
            if (saved.Length != hash.Length)
                return false;
            for (int i = 0; i < saved.Length; i++)
                if (saved[i] != hash[i])
                    return false;
            SaveCrackFile(saved);
            return true;
        }


        private static Func<StreamReader, Byte[]> read_crack_file = reader =>
        {


            var s = reader.ReadToEnd();
            var a = s.Split(new[] { ';' });
            Byte[] h = new Byte[a.Length];
            for (int i = 0; i < a.Length; i++)
                h[i] = Byte.Parse(a[i]);
            return h;

        };

        private static Action<StreamWriter, Byte[]> write_crack_file = (writer, h) =>
        {
            var s = "";
            for (int i = 0; i < h.Length - 1; i++)
                s += h[i] + ";";
            if (h.Length > 0)
                s += h[h.Length - 1];
            writer.Write(s);
        };

        public static void DeleteCrackFile()
        {
            try
            {
                using (var appStorage = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    appStorage.DeleteFile("crack.txt");
                }
            }
            catch (Exception e)
            {
                e.ToString();
            }
        }

        public static void SaveCrackFile(Byte[] h)
        {
            using (var appStorage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                appStorage.DeleteFile("crack.txt");
                using (var streamFile = appStorage.OpenFile("crack.txt", FileMode.OpenOrCreate))
                using (var writer = new StreamWriter(streamFile))
                    write_crack_file(writer, h);
            }
        }

        public static Byte[] GetCrackFile(bool initial_check)
        {
            using (var appStorage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (var streamFile = appStorage.OpenFile("crack.txt", FileMode.OpenOrCreate))
                {
                    try
                    {
                        using (var reader = new StreamReader(streamFile))
                            return read_crack_file(reader);
                    }
                    catch (Exception)
                    {
                        //SaveCrackFile(StateManager.Crack_Hash);
                        if (initial_check)
                            return new Byte[0];
                        else
                            return App.Crack_Hash;
                    }
                }
            }
        }

        #endregion

    }
}
